﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Web.Mvc;
using PizzaMario.Domain.Entities;
using PizzaMario.Domain.Repository;
using PizzaMario.WebApp.Models;

namespace PizzaMario.WebApp.Controllers
{
    public class PizzaMarioController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        private readonly IPizzaRepository _pizzaRepository;
        private readonly IToppingRepository _toppingRepository;

        public PizzaMarioController(IPizzaRepository pizzaRepository, IToppingRepository toppingRepository)
        {
            // Dependency injection ftw :D
            // The contructor for the controller cannot be called manually, hence dependency injection
            _pizzaRepository = pizzaRepository;
            _toppingRepository = toppingRepository;
        }

        [HttpGet]
        public JsonSuccessResult GetAllToppings()
        {
            var toppings = _toppingRepository.All().Select(x => x.Name);

            if( toppings != null )
            {
                return new JsonSuccessResult { Data = toppings.ToList() };
                
            }
            return new JsonSuccessResult { Data = "" };
        }

        private class PizzaSummary
        {
            public String Name { get; set; }
            public List<String> ToppingNames { get; set; }
        }

        [HttpPost]
        public JsonSuccessResult GetPizzasForToppings(List<String> toppings)
        {

            var pizzaList = new List<PizzaSummary>();

            var dbPizzas = _pizzaRepository.All().ToList();

            var foundPizzas = new List<PizzaSummary>();
            foreach(Pizza pizza in dbPizzas)
            {
                int foundToppings = 0;
                foreach (String toppingfromSite in toppings)
                {
                    foreach (Topping t in pizza.Toppings)
                    {
                        if(t.Name.Equals(toppingfromSite))
                        {
                            foundToppings++;
                        }
                    }
                }

                if(foundToppings == toppings.Count )
                {
                    String pizzaName = pizza.Name;
                    List<String> toppingNames = new List<string>();
                    foreach (Topping t in pizza.Toppings)
                    {
                        toppingNames.Add(t.Name);
                    }

                    var newPizza = new PizzaSummary
                    {
                        Name = pizzaName,
                        ToppingNames = toppingNames
                    };

                    pizzaList.Add(newPizza);
                }
            }

            return new JsonSuccessResult { Data = pizzaList };
        }

        [HttpPost]
        public void AddTopping(String toppingName)
        {
            var existingTopping = _toppingRepository.All().FirstOrDefault(x => x.Name.Equals(toppingName, StringComparison.OrdinalIgnoreCase));
            if (existingTopping == null )
            {
                _toppingRepository.Add(new Topping
                {
                    Name = toppingName
                });
                _toppingRepository.SaveChanges();
            }
        }

        [HttpPost]
        public void AddPizza(String pizzaName, List<String> pizzaToppings )
        {
            var toppingList = new List<Topping>();
            foreach (string toppingName in pizzaToppings)
            {
                toppingList.Add( new Topping
                                     {
                                         Name = toppingName
                                     });   
            }

            var newPizza = new Pizza
                            {
                                Name = pizzaName,
                                Toppings = toppingList
                            };

            _pizzaRepository.Add(newPizza);

            //Er vanuit gaande dat alle toppings al bestaan.
            foreach (var topping in newPizza.Toppings)
            {
                var existingTopping = _toppingRepository.All().FirstOrDefault(x => x.Name == topping.Name);
                if (existingTopping != null)
                {
                    //http://nileshhirapra.blogspot.in/2012/03/entity-framework-insert-operation-with.html
                    //At this point all categories in product.Categoires have EntityState added, which we do not want. 
                    //We just want to associate existing categories with product. We are not making any change to such categories. 
                    //So this step explicitly sets their EntityState to unchanged.

                    topping.ToppingId = existingTopping.ToppingId; //Setting ToppingId because topping does not know its primary key(so we give it to him)
                    
                    //Set topping to unchanged so we don't get duplicates!
                    ((IObjectContextAdapter)_pizzaRepository.GetContext()).ObjectContext.ObjectStateManager.
                        ChangeObjectState(topping, EntityState.Unchanged);
                }
            }
            _pizzaRepository.SaveChanges();
        }
    }
}
